/**
 * This file is part of Adaptools.
 * 
 * Adaptools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Adaptools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 * along with Adaptools.  If not, see http://www.gnu.org/licenses/. 
 */
package org.adaptools.core;

import org.adaptools.base.Mechanism;
import org.adaptools.base.MechanismState;
import org.adaptools.base.Queue;
import org.adaptools.filecontroler.AdaptoolsFileController;
import org.adaptools.repository.base.Repository;

/**
 * Abstract class to helps implements {@link AdaptoolsCoreImpl}
 * 
 * @author Denys G. Santos (gsdenys@gmail.com)
 * @since 3.0.0
 */
public abstract class AbstAdaptoolsCore extends Thread implements AdaptoolsCore {

	public final static Integer DEFAULT_TIME_TO_SLEEP = 1000;

	/**
	 * Repository to store the Adaptools execution
	 */
	protected Repository repository = null;

	/**
	 * File controller to manage Adaptools file
	 */
	protected AdaptoolsFileController fileController = null;

	/**
	 * Debug mode variable
	 */
	protected Boolean debugMode = false;

	/**
	 * time that this thread needs to sleep between the execution of 2
	 * transitions
	 */
	protected Integer sleepBetweenTransitions = DEFAULT_TIME_TO_SLEEP;

	/**
	 * check if the mechanism is still in execution
	 * 
	 * @param mechanism
	 * @return {@link Boolean}
	 */
	protected Boolean isMechanismInExecution(Mechanism mechanism) {
		if (mechanism.getMachineState().equals(MechanismState.STARTED)
				|| mechanism.getMachineState().equals(MechanismState.STOPPED)) {
			return Boolean.TRUE;
		}

		return Boolean.FALSE;
	}

	/**
	 * Check if has more elements to read;
	 * 
	 * @return {@link Boolean}
	 */
	protected Boolean hasNext() {
		for (Mechanism mechanism : this.repository.getAllMechanism()) {
			// check if the mechanism is still in execution
			if (isMechanismInExecution(mechanism)) {
				// has more element to be readed in the queue
				Queue queue = mechanism.getQueue();
				if (queue.hasNext()) {
					return Boolean.TRUE;
				}
			}
		}

		return Boolean.FALSE;
	}

	/**
	 * Prepare to read a next queue symbol.
	 */
	protected void nextQueueSymbol() {
		for (Mechanism mechanism : this.repository.getAllMechanism()) {
			// check if the mechanism is still in execution
			if (isMechanismInExecution(mechanism)) {
				// has more element to be readed in the queue
				Queue queue = mechanism.getQueue();
				queue.pull();
			}
		}
	}
	
	
	/**
	 * Sleep function for Adaptools execution
	 */
	protected void sleep() {
		try {
			if (this.sleepBetweenTransitions == null || this.sleepBetweenTransitions == 0) {
				return;
			}
			
			sleep(this.sleepBetweenTransitions);
		} catch (InterruptedException e) {
			System.err.println("It's not normal!!! the system return erro in a sleep(" + this.sleepBetweenTransitions + "); command");
			e.printStackTrace();
		}
	}
	
	
}
